﻿#region License
//------------------------------------------------------------
// Copyright (c) Denis Vuyka.  All rights reserved.
// This source code is subject to terms and conditions of the 
// Microsoft Reciprocal License (Ms-RL) License for Carcass. 
// A copy of the license can be found in the License.txt file 
// at the root of this distribution. 
// By using this source code in any fashion, you are agreeing 
// to be bound by the terms of the 
// Microsoft Reciprocal License (Ms-RL) License
// You must not remove this notice from this software.
//------------------------------------------------------------
#endregion

using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using AvalonDock;
using Carcass.Contents;
using Carcass.Events;
using Carcass.Messaging;
using Carcass.Shell;
using Microsoft.Win32;

namespace DemoShell
{
  /// <summary>
  /// Interaction logic for Shell.xaml
  /// </summary>
  [Export(Carcass.GlobalContracts.MainWindow)]
  public partial class Shell : Window, INotifyImportSatisfaction
  {
    #region Parts

    [Import(Carcass.GlobalContracts.PadManager)]
    private PadManager PadManager { get; set; }

    [Export]
    private DockingManager DockManager { get; set; }

    [Export]
    private DocumentPane DocumentPane { get; set; }

    [Import]
    private IEventAggregator EventAggregator { get; set; }

    [Import]
    private IDocumentService DocumentService { get; set; }

    [Import]
    private IDocumentViewService DocumentViewService { get; set; }

    #endregion

    public Shell()
    {
      InitializeComponent();

      this.DockManager = new DockingManager();

      ResizingPanel panel = new ResizingPanel { Orientation = Orientation.Horizontal };
      this.DockManager.Content = panel;
      this.DocumentPane = new DocumentPane();
      panel.Children.Add(DocumentPane);

      LayoutRoot.Children.Add(this.DockManager);

      this.Loaded += new RoutedEventHandler(Shell_Loaded);

      // Initialize command bindings
      this.CommandBindings.Add(new CommandBinding(ShellCommands.CreateDocument, OnCreateDocumentExecuted));
    }

    private void Shell_Loaded(object sender, RoutedEventArgs e)
    {
      if (PadManager != null)
      {
        foreach (var pad in PadManager.Pads)
        {
          //Add the name of the view to the menu
          MenuItem mi = new MenuItem
          {
            Header = pad.MetadataView.Name,
            Command = ShellCommands.ActivatePad,
            CommandParameter = pad
          };

          ViewMenu.Items.Add(mi);          
        }
      }

      // Populate "File->New" menu      
      foreach (var template in DocumentService.DocumentTemplates)
      {
        MenuItem mi = new MenuItem
        {
          Header = template.MetadataView.DisplayName,          
          Command = ShellCommands.CreateDocument,
          CommandParameter = template.MetadataView.DocumentType
        };

        mnuFileNew.Items.Add(mi);
      }      
    }
        
    public void ImportCompleted()
    {     
      
    }

    private void OnCreateDocumentExecuted(object sender, ExecutedRoutedEventArgs e)
    {
      CreateNewDocument(e.Parameter as string);
    }
              
    private void debugSendMessage_Click(object sender, RoutedEventArgs e)
    {
      if (EventAggregator != null)
      {
        UserMessage message = new UserMessage("Dummy user message...");
        EventAggregator.GetEvent<UserMessagePostedEvent>().Publish(message);
      }
    }

    private void mnuFileOpen_Click(object sender, RoutedEventArgs e)
    {
      string globalFilter = string.Join("|", DocumentService.GetReaderFilters());

      OpenFileDialog fdlg = new OpenFileDialog { Filter = globalFilter };
      if (fdlg.ShowDialog() == true)
      {
        LoadDocument(fdlg.FileName);
      }
    }

    // Creates a new document and displays it within the document pane
    private void CreateNewDocument(string documentType)
    {
      if (string.IsNullOrEmpty(documentType)) throw new ArgumentNullException("documentType");

      var document = DocumentService.CreateDocument(documentType);
      Debug.Assert(document != null, "DocumentFactory failed to create appropriate Document!");
      ShowDocument(document);
    }
        
    private void LoadDocument(string path)
    {      
      var document = DocumentService.LoadDocument(new Uri(path));
      ShowDocument(document); 
    }

    // Creates a view for the document and displays it within the document pane
    private void ShowDocument(Export<IDocument, IDocumentMetadata> document)
    {
      var view = DocumentViewService.CreateView(document.MetadataView).GetExportedObject();      
      view.LoadDocument(document.GetExportedObject());
      this.DocumentPane.ShowDocumentView(view);
    }    
  }
}